package com.example.demo.utils.wx;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.example.demo.utils.common.StringUtils;
import com.example.demo.utils.exception.BusinessException;
import com.example.demo.utils.http.HttpUtils;
import com.example.demo.utils.json.JSONUtils;
import com.example.demo.utils.returned.R;

/**
 * 微信登录
 */
public class WxLoginService {

    /**
     * 集成微信登录
     * code: 移动端需传入code
     * type: APP/JSSDK
     */
    public R<WxLoginInfo> wxLoginApp(String code, String type) {
        WxLoginInfo wxLoginInfo;
        /** 根据传入的code获取授权 access_token openid */
        String accessTokenUrl = WxConfig.accessTokenUrl + (StringUtils.equals(type, WxConfig.FROM_APP) ? WxConfig.appid : WxConfig.publicappid) +
                "&secret=" + (StringUtils.equals(type, WxConfig.FROM_APP) ? WxConfig.appKey : WxConfig.publicappkey) +
                "&code=" + code + "&grant_type=authorization_code";
        String resultInfo = HttpUtils.get(accessTokenUrl);

        try {
            if (StringUtils.isBlank(resultInfo)) {
                return R.fail("登录失败");
            }
            if (resultInfo.contains("errcode")) {
                return R.fail("登录失败");
            }

            JSONObject jsonObject = JSONUtils.toJSONObject(resultInfo);
            String access_token = jsonObject.getString("access_token");
            String openId = jsonObject.getString("openid");
            if (StringUtils.isBlank(access_token) || StringUtils.isBlank(openId)) {
                return R.fail("登录失败");
            }

            /** 获取个人信息 */
            String getUserInfoUrl = WxConfig.getUserInfoUrl + access_token + "&openid=" + openId + "";
            String getUserResponse = HttpUtils.get(getUserInfoUrl);
            if (getUserResponse.contains("errcode")) {
                return R.fail("登录失败");
            }
            wxLoginInfo = JSON.parseObject(getUserResponse, WxLoginInfo.class);
        } catch (Exception e) {
            throw new BusinessException("微信登录失败：" + e.getMessage());
        }
        return R.data(wxLoginInfo);
    }

    /** js sdk 集成微信登录,票据建议存储在服务器，过期时再次获取
     *  url:页面全路径，用于签名
     */
    public R<WxLoginJsSdkPre> wxJsSdkPre(String url) {
        /** todo:获取凭据 */
        String accessToken = WxConfig.jsSdkTokenUrl + WxConfig.publicappid + "&secret=" + WxConfig.publicappkey;
        JSONObject jsonObject = JSONUtils.toJSONObject(HttpUtils.get(accessToken));
        String access = jsonObject.getString("access_token");
        /** todo:获取票据 */
        String getticket = WxConfig.jsSdkTicketUrl + access + "&type=jsapi";
        JSONObject ticketObject = JSONUtils.toJSONObject(HttpUtils.get(getticket));
        String ticket = ticketObject.getString("ticket");
        String timestamp = WxUtil.getTimestamp();
        String noncestr = WxUtil.getRandomString(16);
        // 注意这里参数名必须全部小写，且必须有序
        String str = "jsapi_ticket=" + ticket +
                "&noncestr=" + noncestr +
                "&timestamp=" + timestamp +
                "&url=" + url;
        WxLoginJsSdkPre wxLoginJsSdkPre = new WxLoginJsSdkPre();
        wxLoginJsSdkPre.setAppId(WxConfig.publicappid);
        wxLoginJsSdkPre.setNonceStr(noncestr);
        wxLoginJsSdkPre.setTimestamp(timestamp);
        wxLoginJsSdkPre.setSignature(WxUtil.SHA1(str));
        return R.data(wxLoginJsSdkPre);
    }

}
